from threading import Thread, Lock
import time
import cv2
from .cv_image import add_time_to_image,add_detectedlane_image,add_object_feature_image

class CameraStream:
    OPENCV_NONE=0 
    OPENCV_LANE=1 
    OPENCV_OBJECT_FEATURE=2 
    
    def __init__(self, src=0):
        self.stream = cv2.VideoCapture(src)
        self.stream.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)  # set the width 320
        self.stream.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)  # set the height 240
   
        (self.grabbed, self.frame) = self.stream.read()
        self.started = False
        self.read_lock = Lock()
        self.cur_opencv_action= CameraStream.OPENCV_NONE

    def start(self):
        if self.started:
            print("already started!!")
            return None
        self.started = True
        self.thread = Thread(target=self.update, args=())
        self.daemon=True
        self.thread.start()
        return self

    def update(self):
        while self.started:
            time.sleep(0.1)
            (grabbed, frame) = self.stream.read()
            #  import the opencv mothods to process the image from opencv_image 
            
            # 1 detecting lane  
            if self.cur_opencv_action==CameraStream.OPENCV_NONE:
               result=frame
            elif self.cur_opencv_action==CameraStream.OPENCV_LANE:
               result=add_detectedlane_image(frame)
            elif self.cur_opencv_action==CameraStream.OPENCV_OBJECT_FEATURE:
                result=add_object_feature_image(frame)
                
            # 2 display current time 
            result=add_time_to_image(result)
            
            self.read_lock.acquire()
            self.grabbed, self.frame = grabbed, result
            self.read_lock.release()

    def read(self):
        self.read_lock.acquire()
        frame = self.frame.copy()
        self.read_lock.release()
        return frame

    def stop(self):
        self.started = False
        self.thread.join()

    def __exit__(self, exc_type, exc_value, traceback):
        self.stream.release()